#include"util.hpp"
#include"level.hpp"
#include"message.hpp"
#include"format.hpp"
#include"sink.hpp"
#include"logger.hpp"
#include"buffer.hpp"

namespace viclog
{
enum class TimeGap
{
    GAP_SECOND,
    GAP_MINUTE,
    GAP_HOUR,
    GAP_DAY
};
class RollByTimeSink:public viclog::LogSink
{
    public:
        //构造时传入文件名并打开文件，将操作句柄管理起来
        RollByTimeSink(const std::string& basename,TimeGap gap_type)
        :_basename(basename)
        {
            switch (gap_type)
            {
            case TimeGap::GAP_SECOND: _gap_size=1;break;
            case TimeGap::GAP_MINUTE: _gap_size=60;break;
            case TimeGap::GAP_HOUR: _gap_size=3600;break;
            case TimeGap::GAP_DAY: _gap_size=3600*24;break;

            }
            _cur_gap=_gap_size==1?viclog::util::Date::now():viclog::util::Date::now()%_gap_size;
            std::string pathname=createNewFile();
            //创建日志文件所在目录
            viclog::util::File::createDirectory(viclog::util::File::path(pathname));
            //打开文件
            _ofs.open(pathname,std::ios::binary|std::ios::app);
            assert(_ofs.is_open());

        }
        void log(const char* data,size_t len)
        {
            time_t cur=viclog::util::Date::now();
            if((cur%_gap_size)!=_cur_gap)
            {
                _ofs.close();
                std::string filename=createNewFile();
                _ofs.open(filename,std::ios::binary|std::ios::app);
                assert(_ofs.is_open());
            }
            _ofs.write(data,len);
            assert(_ofs.good());

        }
        private:
        //超过指定大小时创建新文件
         std::string createNewFile()
         {
            //获取系统时间，以系统时间创建文件扩展名
            time_t t=viclog::util::Date::now();
            struct tm lt;
            localtime_r(&t,&lt);
            std::stringstream filename;
            filename<<_basename;
            filename<<lt.tm_year+1900;
            filename<<lt.tm_mon+1;
            filename<<lt.tm_mday;
            filename<<lt.tm_hour;
            filename<<lt.tm_min;
            filename<<lt.tm_sec;
            filename<<"-";
            // filename<<_name_count++;
            filename<<".log";
            return filename.str();


         }
        private:
        std::string _basename;//基础文件名（通过基础文件名+扩展文件名（按时间生产）组成当前实际输出文件名）
        //./log/base--->./log/base-20200922089.log
        
        std::ofstream _ofs;//输出文件的操作句柄
        size_t _cur_gap;//超过max_fsize则切换文件
        size_t _gap_size;//记录当前文件大小
};
}
int main()
{
    // // std::cout<<viclog::util::Date::now()<<std::endl;
    // // std::string pname="./a/b/a.txt";
    // // viclog::util::File::createDirectory( viclog::util::File::path(pname));
    // // std::cout<<viclog::LogLevel::toString(viclog::LogLevel::value::DEBUG)<<std::endl;
    // // std::cout<<viclog::LogLevel::toString(viclog::LogLevel::value::INFO)<<std::endl;
    // // std::cout<<viclog::LogLevel::toString(viclog::LogLevel::value::WARN)<<std::endl;
    // // std::cout<<viclog::LogLevel::toString(viclog::LogLevel::value::OFF)<<std::endl;
    // viclog::LogMsg msg(viclog::LogLevel::value::INFO,10,"main.c","root","格式化测试...");
    // viclog::Formatter fmt;
    // std::string str=fmt.format(msg);
    // // viclog::LogSink::ptr stdout_lsp=viclog::SinkFactory::create<viclog::StdoutSink>();
    // // viclog::LogSink::ptr file_lsp=viclog::SinkFactory::create<viclog::FileSink>("./logfile/test.log");
    // // viclog::LogSink::ptr roll_lsp=viclog::SinkFactory::create<viclog::RollBySizeSink>("./logfile/roll-",1024*1024);
    // viclog::LogSink::ptr time_lsp=viclog::SinkFactory::create<viclog::RollByTimeSink>("./logfile/roll-",viclog::TimeGap::GAP_SECOND);
    // time_t old=viclog::util::Date::now();
    // while(viclog::util::Date::now()<old+5)
    // {
    //     time_lsp->log(str.c_str(),str.size());
    //     usleep(1000);
    // }
    // // stdout_lsp->log(str.c_str(),str.size());
    // // file_lsp->log(str.c_str(),str.size());
    // // size_t cursize=0,count=0;
    // // while(cursize<=1024*1024*10)
    // // {
    // //     cursize+=str.size();
    // //     std::string tmp=str+=std::to_string(count++);
    // //     roll_lsp->log(str.c_str(),str.size());
    // // }

    // std::string loggger_name="sync_logger";
    // viclog::LogLevel::value limit=viclog::LogLevel::value::DEBUG;
    // viclog::Formatter::ptr fmt(new viclog::Formatter("[%d{%H:%M:%S}][%c][%f:%l][%p]%T%m%n"));
    // viclog::LogSink::ptr stdout_lsp=viclog::SinkFactory::create<viclog::StdoutSink>();
    // viclog::LogSink::ptr file_lsp=viclog::SinkFactory::create<viclog::FileSink>("./logfile/test.log");
    // viclog::LogSink::ptr roll_lsp=viclog::SinkFactory::create<viclog::RollBySizeSink>("./logfile/roll-",1024*1024);
    // std::vector<viclog::LogSink::ptr> sinks={stdout_lsp,file_lsp,roll_lsp};
    // viclog::Logger::ptr logger(new viclog::SyncLogger(loggger_name,limit,fmt,sinks));
    // std::unique_ptr<viclog::LoggerBuilder> builder(new viclog::LocalLoggerBuilder());
    // builder->buildLoggerName("sync_logger");
    // builder->buildLoggerLevel(viclog::LogLevel::value::DEBUG);
    // builder->buildFormatter();
    // builder->buildLoggerType(viclog::LoggerType::LOGGER_SYNC);
    // builder->buildSink<viclog::FileSink>("./logfile/test1.log");
    // builder->buildSink<viclog::StdoutSink>();

    //  viclog::Logger::ptr logger=builder->build();
    // logger->debug(__FILE__,__LINE__,"%s","测试。。。");
    // logger->info(__FILE__,__LINE__,"%s","测试。。。");
    // logger->warn(__FILE__,__LINE__,"%s","测试。。。");
    // logger->error(__FILE__,__LINE__,"%s","测试。。。");
    // logger->fatal(__FILE__,__LINE__,"%s","测试。。。");
    // size_t cur_size=0,count=0;
    // while(cur_size<1024*1024*10)
    // {
    //     logger->fatal(__FILE__,__LINE__,"测试-%d",count++);
    //     cur_size+=20;
    // }
    std::ifstream ifs("./logfile/test.log",std::ios::binary);
    if(ifs.is_open()==false ) {return -1;}
    ifs.seekg(0,std::ios::end);
    size_t fsize=ifs.tellg();
    ifs.seekg(0,std::ios::beg);
    std::string body;
    body.resize(fsize);
    ifs.read(&body[0],fsize);
    if(ifs.good()==false) {std::cout<<"read error\n";return -1; }
    ifs.close();
    viclog::Buffer buffer;
    for(int i=0;i<body.size();i++)
    {
        buffer.push(&body[i],1);
    }
    std::ofstream ofs("logfile/tem.log",std::ios::binary);
    size_t rsize=buffer.readAbleSize();
    for(int i=0;i<rsize;i++)
    {
        ofs.write(buffer.begin(),1);
        buffer.moveReader(1);
    }
    ofs.close();
     return 0;
}